package it.utils;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import jpair.api.Field;
import jpair.pairing.BigInt;
import jpair.pairing.EllipticCurve;
import jpair.pairing.Point;

public class Hash {
	
           /*Hash to zp function*/
	public byte[] h3(byte[] toHash, int byteLength){
		if (byteLength<=0)
			throw new IllegalArgumentException("Invalid hash length");
		String hashAlgorithm="SHA-512";
		
		int bitLength =byteLength*8;
		int round;

		if(bitLength<=512){
	
			round=1;

		}
		else{

			round=1+(bitLength-1)/512;
	
		}

		byte[] out = new byte[byteLength];
		
		byte[][] temp = new byte[round][];

		    
	    try {
	        MessageDigest hash = MessageDigest.getInstance(hashAlgorithm);
	        for(int i=0;i<round;i++){
	        	temp[i]=hash.digest(toHash);
	        	toHash=temp[i];
	        }
	    } catch (NoSuchAlgorithmException e) {
	    	System.exit(-1);
	    }
	    
	    int startIndex=0;
	    //int length= byteLength;
	    for(int i=0;i<round;i++){
	    	if(byteLength>=temp[i].length){
	    		System.arraycopy(temp[i], 0, out, startIndex, temp[i].length);
	    		startIndex+=temp[i].length;
	    		byteLength-=temp[i].length;
	    	}
	    	else
	    		System.arraycopy(temp[i], 0, out, startIndex, byteLength);
	    }
	    
	    return out;
		
	}
	
          /* Hasg to Field */
        
	public BigInt h1(byte[] toHash,Field field){
		int byteLength =1+(field.getP().bitLength()-1)/8;
		
		byte[] ba = this.h3(toHash, byteLength);
		
		BigInt b =new BigInt(1,ba);
		
		while(b.compareTo(field.getP())>=0)
			b=b.shiftRight(1);
		
		return b;
		
	}
	
        /* Hasg to Point */
        
	public Point h2(byte[] toHash,EllipticCurve ec){
		
		BigInt b =this.h1(toHash, ec.getField());
		
		Point P =ec.getPoint(b);
		
		while(P==null){
			b=b.add(BigInt.ONE);
			P=ec.getPoint(b);
		}
		return P;
	}
	
        
        /*Hash to Point*/
	public Point h2(byte[] toHash,EllipticCurve ec,BigInt cofactor){
		
		Point P =this.h2(toHash, ec);
		P=ec.multiply(P, cofactor);
		return P;
	}
//	
//	public static void main(String[] args){
//		byte [] ba ="abc".getBytes();
//		
//		byte[] digest =HashUtil.hashToLength(ba, 87);
//		
//	}
	
	public byte[] xorTwoByteArrays(byte[] ba1,byte[] ba2){
		byte [] result =new byte[ba1.length];
		for(int i=0;i<ba1.length;i++){
			 result[i]=(byte) (ba1[i]^ba2[i]);
		}
		return result;
	}
        
        
        public byte[] ByteSum(byte[] ba1,byte[] ba2){
		byte [] result =new byte[ba1.length];
		for(int i=0;i<ba1.length;i++){
			 result[i]=(byte) (ba1[i]^ba2[i]);
		}
		return result;
	}
        
        
           public BigInt h1(byte[] aa, byte[] ab,Field field){
		
           // byte[] toHash;
            byte[] toHash = new byte[aa.length + ab.length];
            System.arraycopy(aa, 0, toHash, 0, aa.length);
            System.arraycopy(ab, 0, toHash, aa.length, ab.length);

  
            
            int byteLength =1+(field.getP().bitLength()-1)/8;
		
		byte[] ba = this.h3(toHash, byteLength);
		
		BigInt b =new BigInt(1,ba);
		
		while(b.compareTo(field.getP())>=0)
			b=b.shiftRight(1);
		
		return b;
		
	}
	
  public String bytearray2string(byte[] _bytes)
{
    String file_string = "";

    for(int i = 0; i < _bytes.length; i++)
    {
        file_string += (char)_bytes[i];
    }

    return file_string;    
}
  public byte[] string2bytearray(String string)
{


    return string.getBytes();    
}

}
